<?php
	require_once("Service.php");
	require_once("Database.php");
	require_once("vo/EventVO.php");
	
	/**
	 * Class which handles all calendar related queries.
	 */
	class CalendarService extends Service {
		
		var $conn;
		
		/** The constructor of this object. */
		function __construct() {
			
			parent::__construct();
			$this->conn = new Database();
		}
		
		/**
		 * Finds a list of upcomming events for a group.
		 * @param $sessionID The session id of the user calling this function.
		 * @param $groupUID The group to find events for.
		 * @param $userUID The user viewing the list.
		 * @return An array of events.
		 */
		function getEventList($sessionID, $groupUID, $userUID) {
			
			$this->validateSession($sessionID);
			
			// get a list of upcomming group events
			$query = Database::buildQuery("
				SELECT
					Events.eventUID,
					Events.groupUID,
					Events.eventDate,
					Events.eventName,
					CASE
						WHEN Reservations.eventUID IS NULL THEN 0
						ELSE 1
					END AS reserved
				FROM Events
				LEFT OUTER JOIN Reservations
					ON Reservations.eventUID = Events.eventUID
					AND Reservations.userUID = ?
				WHERE Events.groupUID = ?
				AND Events.eventDate >= NOW()
				ORDER BY
					Events.eventDate ASC,
					Events.eventName ASC
			", $userUID, $groupUID);
			$qryEvents = $this->conn->execute($query);
			
			$events = array();
			while($recEvents = mysql_fetch_assoc($qryEvents)) {
				$events[] = EventVO::mapObject($recEvents);
			}
			return $events;
		}
		
		/**
		 * Finds the details of a group event.
		 * @param $sessionID The session id of the user calling this function.
		 * @param $eventUID The event to find.
		 * @param $userUID The user viewing the event.
		 * @return An object containing the event.
		 */
		function getEventDetails($sessionID, $eventUID, $userUID) {
			
			$this->validateSession($sessionID);
			
			// get a list of upcomming group events
			$query = Database::buildQuery("
				SELECT
					Events.eventUID,
					Events.groupUID,
					Events.eventDate,
					Events.eventName,
					Events.description,
					CASE
						WHEN Reservations.eventUID IS NULL THEN 0
						ELSE 1
					END AS reserved
				FROM Events
				LEFT OUTER JOIN Reservations
					ON Reservations.eventUID = Events.eventUID
					AND Reservations.userUID = ?
				WHERE Events.eventUID = ?
			", $userUID, $eventUID);
			$qryEvents = $this->conn->execute($query);
			
			$recEventDetails = mysql_fetch_assoc($qryEvents);
			return EventVO::mapObject($recEventDetails);
		}
		
		/**
		 * RSVPs a user for an event.
		 * @param $sessionID The session id of the user calling this function.
		 * @param $eventUID The event to RSVP for.
		 * @param $userUID The user to RSVP.
		 * @param $unrsvp True to remove an existing reservation, false to add a new one.
		 */
		function rsvpEvent($sessionID, $eventUID, $userUID, $unrsvp=false) {
			
			$this->validateSession($sessionID);
			
			if($unrsvp) {
				
				// deletes a user's reservation
				$query = Database::buildQuery("
					DELETE FROM Reservations
					WHERE eventUID = ?
					AND userUID = ?
				", $eventUID, $userUID);
				
			} else {
				
				// make a user reservation
				$query = Database::buildQuery("
					INSERT INTO Reservations(eventUID, userUID)
					VALUES (?, ?)
				", $eventUID, $userUID);
			}
			
			$this->conn->execute($query);
		}
		
		/**
		 * Saves a new calendar event on a group.
		 * @param $sessionID The sessionID of the user calling this function.
		 * @param $groupUID The group on which the event was added.
		 * @param $eventDate The date the event will be held.
		 * @param $eventName The name of the event.
		 * @param $description The description of the event.
		 * @return The eventUID of the saved event.
		 */
		function addEvent($sessionID, $groupUID, $eventDate, $eventName, $description) {
			
			$this->validateSession($sessionID);
			
			$eventUID = $this->conn->generateUID();
			
			// save the event
			$query = Database::buildQuery("
				INSERT INTO Events (
					eventUID,
					groupUID,
					eventDate,
					eventName,
					description
				) VALUES (?, ?, ?, ?, ?)
			", $eventUID, $groupUID, $eventDate, $eventName, $description);
			$this->conn->execute($query);
			
			return $eventUID;
		}
		
		/**
		 * Updates the details of a calendar event.
		 * @param $sessionID The sessionID of the user calling this function.
		 * @param $eventUID The event to update.
		 * @param $eventDate The date the event will be held.
		 * @param $eventName The name of the event.
		 * @param $description The description of the event.
		 * @return The eventUID of the updated event.
		 */
		function editEvent($sessionID, $eventUID, $eventDate, $eventName, $description) {
			
			$this->validateSession($sessionID);
			
			// update the event
			$query = Database::buildQuery("
				UPDATE Events
				SET
					eventDate = ?,
					eventName = ?,
					description = ?
				WHERE eventUID = ?
			", $eventDate, $eventName, $description, $eventUID);
			$this->conn->execute($query);
			
			return $eventUID;
		}
		
		/**
		 * Deletes an calendar event.
		 * @param $sessionID The sessionID of the user calling this function.
		 * @param $eventUID The event to delete.
		 * @return The eventUID of the deleted event.
		 */
		function deleteEvent($sessionID, $eventUID) {
			
			$this->validateSession($sessionID);
			
			$queries = array();
			
			// delete linked reservations
			$queries[] = Database::buildQuery("
				DELETE FROM Reservations
				WHERE eventUID = ?
			", $eventUID);
			
			// delete the event
			$queries[] = Database::buildQuery("
				DELETE FROM Events
				WHERE eventUID = ?
			", $eventUID);
			
			$this->conn->transaction($queries);
			
			return $eventUID;
		}
	}
?>